package com.vtuzx.kingdee.xqc_core.dao;

import com.vtuzx.core.db.mongo.impl.VtuzxDaoImpl;
import com.vtuzx.core.utils.VtuzxUtil;
import com.vtuzx.kingdee.xqc_core.bean.VtuzxArrayList;
import org.bson.Document;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Component;

import javax.print.Doc;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * 即时库存Dao
 */
@Component
public class InventoryDao extends VtuzxDaoImpl {
    /** 集合名 */
    public static final String NAME = "t_inventory";
    /**
     * 构造
     */
    public InventoryDao() {
        super(NAME);
    }

    /**
     * 插入即时库存
     *
     * @param _userId 用户ID
     * @param userName 用户名
     * @param doc 文档
     * @return 库存ID
     */
    public ObjectId insertStock(ObjectId _userId, String userName, Document doc) {
        doc.append("_createUserId", _userId);
        doc.append("createUserName", userName);
        doc.append("_updateUserId", _userId);
        doc.append("updateUserName", userName);
        return insertOne(doc);
    }

    /**
     * 更新即时库存
     *
     * @param _userId 用户ID
     * @param userName 用户名
     * @param _id 文档ID
     * @param incDoc 文档
     */
    public void updateStock(ObjectId _userId, String userName, ObjectId _id, Document incDoc) {
        Document updateDoc = new Document();
        updateDoc.append("_updateUserId", _userId);
        updateDoc.append("updateUserName", userName);
        updateByIdRedirect(_id, new Document("$set", updateDoc).append("$inc", incDoc));
    }

    public Document statStock(Criteria cond) {
        List<Document> docList = new ArrayList<>();
        docList.add(new Document("$match", cond.getCriteriaObject()));
        docList.add(new Document("$group",
                new Document("_id", null).append("totalBoxCount", new Document("$sum", "$boxCount")).append("totalCount", new Document("$sum", "$count"))));

        Iterator<Document> resItr = this.aggregate(docList);
        if (resItr.hasNext()) {
            return resItr.next();
        }
        return null;
    }

    public Iterator<Document> findInventoryList(Criteria cond) {
        List<Document> docList = new ArrayList<>();
        docList.add(new Document("$lookup", new Document("from", InventoryDetailDao.NAME).append("foreignField", "_inventoryId").append("localField", "_id").append("as", "inventorydetail")));
        docList.add(new Document("$unwind", new Document("path", "$inventorydetail")));
        docList.add(new Document("$match", cond.getCriteriaObject()));
        docList.add(new Document("$group",
                new Document("_id", new Document("batchNo", "$batchNo").append("locationNo","$inventorydetail.locationNo").append("stockNo","$stockNo").append("materialNo","$materialNo"))
                        .append("boxCount", new Document("$sum", 1)).append("count", new Document("$sum", "$inventorydetail.count"))));
        return this.aggregate(docList);
    }


    public Iterator<Document> findAllMaterial(Criteria cond, Document sort, int pageIndex, int pageSize) {
        List<Document> docList = new ArrayList<>();
        docList.add(new Document("$match", cond.getCriteriaObject()));
        docList.add(new Document("$group",
                new Document("_id", new Document("stockNo","$stockNo").append("materialNo","$materialNo").append("batchNo","$batchNo"))

                        .append("count", new Document("$sum", 1))));
        if (sort != null) {
            docList.add(new Document("$sort", sort));
        }
        if (pageIndex > 0 && pageSize > 0) {
            docList.add(new Document("$skip", pageIndex * pageSize));
        }
        if (pageSize > 0) {
            docList.add(new Document("$limit", pageSize));
        }
        return this.aggregate(docList);
    }

    /**
     * 查询原料库存
     * @param cond
     * @param sort
     * @param pageIndex
     * @param pageSize
     * @return
     */
    public Iterator<Document> findRawMaterial(Criteria cond, Document sort, int pageIndex, int pageSize) {
        List<Document> docList = new ArrayList<>();
        docList.add(new Document("$match", cond.getCriteriaObject()));
        docList.add(new Document("$group",
                new Document("_id", new Document("stockNo","$stockNo").append("materialNo","$materialNo"))

                        .append("count", new Document("$sum", "$count"))));
        if (sort != null) {
            docList.add(new Document("$sort", sort));
        }
        if (pageIndex > 0 && pageSize > 0) {
            docList.add(new Document("$skip", pageIndex * pageSize));
        }
        if (pageSize > 0) {
            docList.add(new Document("$limit", pageSize));
        }
        return this.aggregate(docList);
    }

    public int countAllMaterial(Criteria cond) {
        List<Document> docList = new ArrayList<>();
        docList.add(new Document("$match", cond.getCriteriaObject()));
        docList.add(new Document("$group",
                new Document("_id", new Document("stockNo","$stockNo").append("materialNo","$materialNo") .append("batchNo","$batchNo"))
                        .append("count", new Document("$sum", 1))));
        docList.add(new Document("$group",
                new Document("_id", null).append("count", new Document("$sum", 1))));
        Iterator<Document> itr = this.aggregate(docList);
        if (itr.hasNext()) {
            return VtuzxUtil.getObject(itr.next(), "count");
        }
        return 0;
    }
}
